<!-- EpubReader.vue -->
<template>
    <div class="epub-reader">
        <h2>{{ bookTitle }}</h2>

        <!-- 目录 -->
        <div v-if="tableOfContents.length > 0" class="toc-panel">
            <h3 @click="showToc = !showToc" style="cursor: pointer;">
                📚 目录 (点击切换)
            </h3>
            <ul v-if="showToc">
                <li v-for="(item, index) in tableOfContents" :key="index"
                    :style="{ marginLeft: item.level * 16 + 'px' }">
                    <a href="#" @click.prevent="jumpToSection(item.href)"
                        :class="{ active: isCurrentSection(item.href) }">
                        {{ item.label }}
                    </a>
                </li>
            </ul>
        </div>

        <!-- EPUB 渲染容器 -->
        <div ref="epubView" class="epub-container"></div>

        <!-- 章节导航 -->
        <div class="chapter-controls" v-if="canNavigateChapters">
            <button @click="prevChapter" :disabled="!hasPrevChapter">◀ 上一章</button>
            <button @click="nextChapter" :disabled="!hasNextChapter">下一章 ▶</button>
        </div>

        <!-- 翻页 -->
        <div class="pagination-controls">
            <button @click="prevPage">◀ 上一页</button>
            <button @click="nextPage">下一页 ▶</button>
        </div>

        <!-- 错误提示 -->
        <p v-if="errorMessage" class="error">{{ errorMessage }}</p>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';

// 类型定义（简化）
interface Epub {
    loaded: {
        metadata: Promise<{ title: string }>;
        navigation: Promise<{ toc: RawTocItem[] }>;
    };
    spine: {
        items: SpineItem[];
        length: number;
        get: (index: number) => SpineItem | null;
    };
    packaging: { manifest: Record<string, string> };
    destroy?: () => void;
}

interface SpineItem {
    id: string;
    href: string;
    cfi: string;
    linear: string;
}

interface RawTocItem {
    label: string;
    href: string;
    subitems?: RawTocItem[];
}

interface TocItem {
    label: string;
    href: string;
    level: number;
}

// Refs
const epubView = ref<HTMLElement | null>(null);
const bookTitle = ref<string>('加载中...');
const errorMessage = ref<string>('');
const tableOfContents = ref<TocItem[]>([]);
const showToc = ref<boolean>(false);
const currentSectionHref = ref<string>('');

let book: Epub | null = null;
let rendition: any = null;

// EPUB 文件路径
const epubUrl = '/books/sample.epub'; // 放在 public/books/

// 动态导入 epubjs
const loadEpub = async () => {
    try {
        const module = await import('epubjs');
        return module.default || module;
    } catch (error) {
        console.error('Failed to load epubjs:', error);
        throw error;
    }
};

onMounted(async () => {
    errorMessage.value = '';
    try {
        const Epub = await loadEpub();

        book = new Epub(epubUrl) as Epub;

        if (!epubView.value) throw new Error('epubView 容器未挂载');

        // 🔥 关键修复：启用 allow-scripts，允许脚本执行（解决沙箱问题）
        rendition = book.renderTo(epubView.value, {
            width: '100%',
            height: 600,
            flow: 'scrolled',
            method: 'default',
            // ✅ 允许脚本执行（必须）
            allowScriptedContent: true,
            // ✅ 沙箱配置允许脚本（关键）
            sandbox: {
                allow: [
                    'scripts',
                    'same-origin',
                    'popups',
                    'forms'
                ]
            }
        });

        // 元数据
        const metadata = await book.loaded.metadata;
        bookTitle.value = metadata.title || '未知标题';

        // 目录
        const nav = await book.loaded.navigation;
        const toc: TocItem[] = [];

        const flatten = (items: RawTocItem[], level = 0) => {
            for (const item of items) {
                toc.push({ label: item.label, href: item.href, level });
                if (item.subitems) {
                    flatten(item.subitems, level + 1);
                }
            }
        };
        flatten(nav.toc);
        tableOfContents.value = toc;

        // 监听位置变化
        rendition.on('relocated', (location: any) => {
            const spineItem = book?.spine.items.find(item => item.cfi === location.start.cfi);
            if (spineItem) {
                currentSectionHref.value = spineItem.href;
            }
        });

        // 显示正文
        await displayFirstContentChapter();

        console.log('✅ EPUB 已成功加载并渲染');
    } catch (error: any) {
        console.error('❌ 加载失败:', error);
        errorMessage.value = error.message || '加载失败';
        bookTitle.value = `加载失败: ${error.message}`;
    }
});

// ========== 路径解析与跳转 ==========
const resolveHref = (tocHref: string): string => {
    // 处理相对路径：匹配 spine 中的 href
    const target = book?.spine.items.find(item => {
        const itemBase = item.href.split('/').pop();
        const hrefBase = tocHref.split('/').pop();
        return itemBase === hrefBase;
    });
    return target ? target.href : tocHref;
};

const jumpToSection = (href: string) => {
    const resolved = resolveHref(href);
    rendition.display(resolved).catch(err => {
        console.error('跳转失败:', err);
    });
};

const isCurrentSection = (href: string): boolean => {
    return currentSectionHref.value === resolveHref(href);
};

// ========== 章节导航 ==========
const prevChapter = () => {
    const items = book?.spine.items || [];
    const idx = items.findIndex(item => item.href === currentSectionHref.value);
    if (idx > 0) {
        rendition.display(items[idx - 1].href);
    }
};

const nextChapter = () => {
    const items = book?.spine.items || [];
    const idx = items.findIndex(item => item.href === currentSectionHref.value);
    if (idx < items.length - 1) {
        rendition.display(items[idx + 1].href);
    }
};

const hasPrevChapter = computed(() => {
    const items = book?.spine.items || [];
    const idx = items.findIndex(item => item.href === currentSectionHref.value);
    return idx > 0;
});

const hasNextChapter = computed(() => {
    const items = book?.spine.items || [];
    const idx = items.findIndex(item => item.href === currentSectionHref.value);
    return idx < items.length - 1;
});

const canNavigateChapters = computed(() => {
    return book?.spine.items.length > 1;
});

// ========== 翻页 ==========
const prevPage = () => {
    rendition.prev();
};

const nextPage = () => {
    rendition.next();
};

// ========== 显示第一个内容章节 ==========
const displayFirstContentChapter = async () => {
    const items = book?.spine.items || [];
    const contentItem = items.find(item => {
        return !/(cover|titlepage|copyright|toc|nav)\.xhtml$/i.test(item.href);
    }) || items[0];

    if (contentItem) {
        await rendition.display(contentItem.href);
        currentSectionHref.value = contentItem.href;
    }
};

// ========== 销毁 ==========
onBeforeUnmount(() => {
    if (rendition) {
        rendition.destroy?.();
        rendition = null;
    }
    if (book?.destroy) {
        book.destroy();
    }
    book = null;
});
</script>

<style scoped>
.epub-reader {
    max-width: 900px;
    margin: 0 auto;
    padding: 20px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

.toc-panel {
    margin: 20px 0;
    padding: 15px;
    background-color: #f8f9fa;
    border: 1px solid #dee2e6;
    border-radius: 8px;
}

.toc-panel h3 {
    margin: 0 0 10px 0;
}

.toc-panel ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.toc-panel a {
    color: #007bff;
    text-decoration: none;
    font-size: 14px;
    line-height: 1.8;
    display: block;
}

.toc-panel a:hover {
    text-decoration: underline;
}

.toc-panel a.active {
    font-weight: bold;
    color: #e91e63;
}

.epub-container {
    margin: 20px 0;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
    width: 100%;
    height: 600px;
    background: #fff;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.epub-container iframe {
    width: 100%;
    height: 100%;
    border: none;
}

.error {
    color: #d32f2f;
    background: #ffebee;
    padding: 10px;
    border-radius: 4px;
    font-size: 14px;
    margin-top: 10px;
}

.chapter-controls,
.pagination-controls {
    margin: 10px 0;
    text-align: center;
}

.chapter-controls button,
.pagination-controls button {
    margin: 0 8px;
    padding: 8px 16px;
    font-size: 14px;
    cursor: pointer;
    background: #1976d2;
    color: white;
    border: none;
    border-radius: 4px;
}

.chapter-controls button:disabled,
.pagination-controls button:disabled {
    background: #ccc;
    cursor: not-allowed;
}
</style>